using System.Collections.Generic;
using UnityEngine;

namespace VoxelEngine
{
	public static class ChunkCollider
	{
		private static List<Vector3> _vertices = new List<Vector3>();

		private static List<int> _triangles = new List<int>();

		public static void Free()
		{
			_vertices.Clear();
			_triangles.Clear();
		}

		public static Mesh BuildGreedyCollider(Chunk chunk, Mesh mesh)
		{
			if (mesh == null)
			{
				mesh = new Mesh();
				mesh.MarkDynamic();
			}
			int num = 8;
			_vertices.Clear();
			_triangles.Clear();
			int[] array = new int[(num + 1) * (num + 1)];
			int num2 = 0;
			for (int i = 0; i < 3; i++)
			{
				int num3 = (i + 1) % 3;
				int num4 = (i + 2) % 3;
				int[] array2 = new int[3];
				int[] array3 = new int[3];
				array3[i] = 1;
				array2[i] = -1;
				while (array2[i] < num)
				{
					int num5 = 0;
					array2[num4] = 0;
					while (array2[num4] < num)
					{
						array2[num3] = 0;
						while (array2[num3] < num)
						{
							Block block = chunk[array2[0], array2[1], array2[2]];
							int num6 = 0;
							if (0 <= array2[i] && block.IsSolid())
							{
								num6 = 1;
							}
							int num7 = 0;
							Block block2 = chunk[array2[0] + array3[0], array2[1] + array3[1], array2[2] + array3[2]];
							if (array2[i] < num - 1 && block2.IsSolid())
							{
								num7 = 1;
							}
							if (num6 == num7)
							{
								array[num5] = 0;
							}
							else if (num6 > 0)
							{
								array[num5] = num6;
							}
							else
							{
								array[num5] = -num7;
							}
							array2[num3]++;
							num5++;
						}
						array2[num4]++;
					}
					array2[i]++;
					num5 = 0;
					for (int j = 0; j < num; j++)
					{
						int num8 = 0;
						while (num8 < num)
						{
							int num9 = array[num5];
							if (num9 > -2)
							{
								int k;
								for (k = 1; num9 == array[num5 + k] && num8 + k < num; k++)
								{
								}
								bool flag = false;
								int l;
								for (l = 1; j + l < num; l++)
								{
									for (int m = 0; m < k; m++)
									{
										if (num9 != array[num5 + m + l * num])
										{
											flag = true;
											break;
										}
									}
									if (flag)
									{
										break;
									}
								}
								bool flag2 = false;
								array2[num3] = num8;
								array2[num4] = j;
								int[] array4 = new int[3];
								int[] array5 = new int[3];
								if (num9 > -1)
								{
									array4[num3] = k;
									array5[num4] = l;
								}
								else
								{
									flag2 = true;
									num9 = -num9;
									array4[num3] = k;
									array5[num4] = l;
								}
								Vector3 vector = new Vector3(array2[0], array2[1], array2[2]);
								Vector3 vector2 = new Vector3(array2[0] + array4[0], array2[1] + array4[1], array2[2] + array4[2]);
								Vector3 vector3 = new Vector3(array2[0] + array4[0] + array5[0], array2[1] + array4[1] + array5[1], array2[2] + array4[2] + array5[2]);
								Vector3 vector4 = new Vector3(array2[0] + array5[0], array2[1] + array5[1], array2[2] + array5[2]);
								if (num9 > 0 && !flag2)
								{
									AddFace(vector, vector2, vector3, vector4, _vertices, _triangles, 0);
									num2 += 4;
								}
								else if (flag2)
								{
									AddFace(vector4, vector3, vector2, vector, _vertices, _triangles, 0);
									num2 += 4;
								}
								for (int n = 0; n < l; n++)
								{
									for (int m = 0; m < k; m++)
									{
										array[num5 + m + n * num] = 0;
									}
								}
								num8 += k;
								num5 += k;
							}
							else
							{
								num8++;
								num5++;
							}
						}
					}
				}
			}
			mesh.SetVertices(_vertices);
			mesh.SetTriangles(_triangles, 0);
			return mesh;
		}

		private static void AddFace(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, List<Vector3> vertices, List<int> triangles, int order)
		{
			if (order == 0)
			{
				int count = vertices.Count;
				vertices.Add(v1);
				vertices.Add(v2);
				vertices.Add(v3);
				vertices.Add(v4);
				triangles.Add(count);
				triangles.Add(count + 1);
				triangles.Add(count + 2);
				triangles.Add(count + 2);
				triangles.Add(count + 3);
				triangles.Add(count);
			}
			if (order == 1)
			{
				int count2 = vertices.Count;
				vertices.Add(v1);
				vertices.Add(v2);
				vertices.Add(v3);
				vertices.Add(v4);
				triangles.Add(count2);
				triangles.Add(count2 + 3);
				triangles.Add(count2 + 2);
				triangles.Add(count2 + 2);
				triangles.Add(count2 + 1);
				triangles.Add(count2);
			}
		}
	}
}
